1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
//! Manipulate the probabilities of working on different solutions.
//!
//! A portion of the bees in an artificial bee colony are tasked with observing
//! the dedicated workers, and doing extra work on promising solutions. To
//! enable this, the solutions' fitnesses are gathered as a `Vec<f64>`. A
//! [`FitnessScaler`](type.FitnessScaler.html) is then run on the fitnesses to
//! get weighting factors, and a solution is chosen with likelihood
//! proportionate to its scaled fitness. This is expressed as:
//!
//! <center>P(*i*) = *scaled*<sub>*i*</sub>
//! / ∑<sub>*j* = 1 … N</sub> *scaled*<sub>*j*</sub></center>
//!
//! By default, [proportionate](fn.proportionate.html) scaling is used.
//!
//! To construct a custom FitnessScaler, you can use the
//! [`scale_by!`](../macro.scale_by!.html) macro provided.
//!
//! # Examples
//!
//! Several constructors for scaling functions are available in this module.
//! However, users may also implement custom scaling functions. These can
//! exaggerate differences in fitness:
//!
//! ```
//! # #[macro_use] extern crate abc; fn main() {
//! scale_by!(fitnesses => {
//! // Square the fitnesses.
//! fitnesses.iter().map(|fitness| fitness.powf(2f64)).collect()
//! });
//! # }
//! ```
pub use Arc;
use Deref;
pub type Callback = Fn + Send + Sync + 'static;
/// Map a vector of fitnesses to a vector of scaled fitnesses.
///
/// For more information, see the [module docs](index.html).
/// Construct a custom FitnessScaler.
///
/// The body of this macro includes a name and a formula. These will be used to
/// construct a closure that always takes a `Vec<f64>` and returns a `Vec<f64>`,
/// and that always uses `move`.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate abc;
///
/// # fn main() {
/// scale_by!(fits => fits.iter().map(|f| -f).collect());
/// # }
/// ```
///
/// As with a closure, the formula can be a block:
///
/// ```
/// # #[macro_use] extern crate abc; fn main() {
/// scale_by!(fitnesses => {
/// // Bring all fitnesses halfway towards the mean.
/// let length = fitnesses.len() as f64;
/// let mean = fitnesses.iter().fold(0f64, |total, x| total + x) / length;
/// fitnesses.iter().map(|x| x - (x - mean) / 2f64).collect()
/// });
/// # }
/// ```
/// Choose solutions in direct proportion to their fitness.
///
/// scaled<sub>*i*</sub> = fitness<sub>*i*</sub>
/// Choose more fit solutions exponentially more often.
///
/// scaled<sub>*i*</sub> = fitness<sub>*i*</sub><sup>*k*</sup>
/// Choose solutions according to their rank.
///
/// Rather than use the fitness directly, this formula ranks the N solutions
/// 1 to N, in ascending order of fitness, then chooses in proportion to the
/// value of the rank. So, the solution with rank 6 will be chosen twice as
/// often as the solution with rank 3, and three times as often as the solution
/// with rank 2.
///
/// scaled<sub>*i*</sub> = rank<sub>*i*</sub>
/// Choose solutions according to their rank, raised to a certain power.
///
/// This scaling formula was proposed by Yudong Zhang et al for the
/// Fitness-Scaling Chaotic ABC in the 2013 volume of *Mathematical Problems
/// in Engineering*. Conceptually, it composes the [power](fn.power.html) and
/// [rank](fn.rank.html) scaling techniques.
///
/// scaled<sub>*i*</sub> = rank<sub>*i*</sub><sup>*k*</sup>
///
/// As with rank scaling, rank<sub>*i*</sub> starts with 1 for the least fit,
/// and continues up to N for the most fit.